import React from 'react';
import axios from 'axios';
import { message } from 'antd';
import 'antd/dist/antd.css';

class Luckysheet extends React.Component {

  componentDidMount () {
    //export excel function end
    const luckysheet = window.luckysheet;
    const luckyExcel = window.LuckyExcel;
    const ExcelJS = window.ExcelJS;
    const getDPI = window.js_getDPI;
    const defaultHeight = 25;
    const defaultWidth = 40;
    const [dpix, dpiy] = getDPI();
    let xlsxname = "虚拟资源使用申请表-20210204154646.xlsx";
    let suffixArr = xlsxname.split("."), suffix = suffixArr[suffixArr.length - 1];
    if (suffix !== "xlsx") {
      alert("Currently only supports the import of xlsx files");
      return;
    }
    // export excel function

    function exportExcel (luckysheet, value) {
      console.log(luckysheet);
      const workbook = new ExcelJS.Workbook();
      // 2.创建表格，第二个参数可以配置创建什么样的工作表
      if (Object.prototype.toString.call(luckysheet) === '[object Object]') {
        luckysheet = [luckysheet]
      }
      luckysheet.forEach(function (table) {
        if (table.data.length === 0) return true
        // ws.getCell('B2').fill = fills.
        const worksheet = workbook.addWorksheet(table.name, { pageSetup: {} })
        const merge = (table.config && table.config.merge) || {}
        const borderInfo = (table.config && table.config.borderInfo) || {}
        const images = (table.images) || {}
        const visibledatarow = table.config.rowlen || {};
        const visibledatacolumn = table.config.columnlen || {};
        // 3.设置单元格合并,设置单元格边框,设置单元格样式,设置值
        setStyleAndValue(table.data, worksheet);
        setMerge(merge, worksheet);
        setBorder(borderInfo, worksheet);
        setCellDefault(worksheet);
        setCellRow(visibledatarow, worksheet);
        setCellCol(visibledatacolumn, worksheet);
        setImage(images, visibledatarow, visibledatacolumn, workbook, worksheet);
        return true
      })

      // return
      // 4.写入 buffer
      const buffer = workbook.xlsx.writeBuffer().then(data => {
        const blob = new Blob([data], {
          type: 'application/vnd.ms-excel;charset=utf-8'
        })
        //console.log("导出成功！")
        //saveAs函数式FileSaver.js中导出的函数

        let formData = new FormData();
        formData.append('file', blob, value);
        axios.put('/api/file/' + value, formData, { headers: { "Conten-Type": "multipart/form-data" } }).then(res => {
          message.success("保存成功 [  {0}  ]".format(res.data.destination));
        }).catch(error => {
          message.error("保存失败 [  {0}  ]".format(error));
        });
      })
      return buffer
    }
    var setCellDefault = function (worksheet) {
      worksheet.properties.defaultRowHeight = defaultHeight;
      worksheet.properties.defaultColWidth = defaultWidth;
    }
    // 1英寸=2.54cm=25.4mm=dpi像素
    //dpi/25.4是每毫米的像素个数
    //1mm=2.86磅
    //dpi/(25.4*2.86)是每磅的像素个数
    //x是磅 y是像素  那么【 x*dpi/(25.4*2.86)=y】

    var setCellRow = function (visibledatarow, worksheet) {
      for (let x in visibledatarow) {
        worksheet.getRow(parseInt(x) + 1).height =
          Math.round(visibledatarow[x] * (25.4 * 2.86) / dpiy);
      }
    }
    var setCellCol = function (visibledatacolumn, worksheet) {
      for (let x in visibledatacolumn) {
        worksheet.getColumn(parseInt(x) + 1).width = Math.round((visibledatacolumn[x] + 1) / 8);
      }
    }
    //只能用excel改变图片，保存会还原，因为我用的是default的位置
    var setImage = function (images, visibledatarow, visibledatacolumn, workbook, worksheet) {
      for (let x in images) {
        const imagetag = images[x].src.split(';base64,')[0].split('data:image/')[1];
        const imgid = workbook.addImage({ base64: images[x].src, extension: imagetag });
        //第一次创建时，或者之前的图片做了移动，或者之前图片没移动===》所有图片都会进入
        //，计算比较麻烦，需要使用像素来计算 
        if (images[x].default.height != null && images[x].default.width != null && images[x].default.top != null && images[x].default.left != null) {
          let image_left = images[x].default.left;
          let image_top = images[x].default.top;
          let image_height = images[x].default.height;
          let image_width = images[x].default.width;
          let temp_px = 0;
          let tag = false;
          let image_lcol = 0;
          let image_rcol = 0;
          let image_lrow = 0;
          let image_hrow = 0;

          for (let i = 0; ; i++) {
            let this_px = ((i.toString() in visibledatacolumn) ? (visibledatacolumn[i.toString()]) : Math.round(defaultWidth * 8 - 1));
            temp_px = temp_px + this_px;
            if (!tag && (temp_px >= image_left)) {
              tag = true;
              image_lcol = i + (image_left - temp_px + this_px) / this_px;
            }
            if (temp_px >= (image_left + image_width)) {
              image_rcol = i + ((image_left + image_width) - temp_px + this_px) / (this_px);
              break;
            }
            if (i > 10000) {
              break;
              console.log('错误：数据已经超过1W列');
            }

          }
          temp_px = 0;
          tag = false;
          for (let i = 0; ; i++) {

            let this_px = ((i.toString() in visibledatarow) ? (visibledatarow[i.toString()]) : Math.round(1 + defaultHeight * dpiy / (25.4 * 2.86)));
            temp_px = temp_px + this_px;
            if (!tag && (temp_px >= image_top)) {
              tag = true;
              image_lrow = i + (image_top - temp_px + this_px) / (this_px);
            }
            if (temp_px >= (image_top + image_height)) {
              image_hrow = i + ((image_top + image_height) - temp_px + this_px) / (this_px);
              break;
            }
            if (i > 10000) {
              break;
              console.log('错误：数据已经超过1W行');
            }
          }
          worksheet.addImage(imgid, {
            tl: {
              col: image_lcol,
              row: image_lrow
            },
            br: {
              col: image_rcol,
              row: image_hrow
            },
            editAs: 'absolute'
          });
        }
        //不是第一次创建，图片也没有移动
        else if (('fromCol' in images[x]) && ('fromRow' in images[x]) && ('toCol' in images[x]) && ('toRow' in images[x]) &&
          images[x].fromCol != null && images[x].fromRow != null && images[x].toRow != null && images[x].toCol != null
        ) {
          worksheet.addImage(imgid, {
            tl: {
              col: images[x].fromCol + images[x].fromColOff / (visibledatacolumn[images[x].fromCol] === undefined ? Math.round(defaultWidth * 8 - 1) : visibledatacolumn[images[x].fromCol]),
              row: images[x].fromRow + images[x].fromRowOff / (visibledatarow[images[x].fromRow] === undefined ? Math.round(defaultHeight * dpiy / (25.4 * 2.86)) : visibledatarow[images[x].fromRow])
            },
            br: {
              col: images[x].toCol + images[x].toColOff / (visibledatacolumn[images[x].toCol] === undefined ? Math.round(defaultWidth * 8 - 1) : visibledatacolumn[images[x].toCol]),
              row: images[x].toRow + images[x].toRowOff / (visibledatarow[images[x].toRow] === undefined ? Math.round(defaultHeight * dpiy / (25.4 * 2.86)) : visibledatarow[images[x].toRow])
            },
            editAs: 'absolute'
          });
        } else {
          console.log('存在错误的图片: ', images[x]);
        }

      }
    }
    var setMerge = function (luckyMerge = {}, worksheet) {
      const mergearr = Object.values(luckyMerge)
      mergearr.forEach(function (elem) {
        // elem格式：{r: 0, c: 0, rs: 1, cs: 2}
        // 按开始行，开始列，结束行，结束列合并（相当于 K10:M12）
        worksheet.mergeCells(
          elem.r + 1,
          elem.c + 1,
          elem.r + elem.rs,
          elem.c + elem.cs
        )
      })
    }

    var setBorder = function (luckyBorderInfo, worksheet) {
      if (!Array.isArray(luckyBorderInfo)) return
      // console.log('luckyBorderInfo', luckyBorderInfo)
      luckyBorderInfo.forEach(function (elem) {
        // 现在只兼容到borderType 为range的情况
        // console.log('ele', elem)
        if (elem.rangeType === 'range') {
          let border = borderConvert(elem.borderType, elem.style, elem.color)
          let rang = elem.range[0]
          // console.log('range', rang)
          let row = rang.row
          let column = rang.column
          for (let i = row[0] + 1; i < row[1] + 2; i++) {
            for (let y = column[0] + 1; y < column[1] + 2; y++) {
              worksheet.getCell(i, y).border = border
            }
          }
        }
        if (elem.rangeType === 'cell') {
          // col_index: 2
          // row_index: 1
          // b: {
          //   color: '#d0d4e3'
          //   style: 1
          // }
          const { col_index, row_index } = elem.value
          const borderData = Object.assign({}, elem.value)
          delete borderData.col_index
          delete borderData.row_index
          let border = addborderToCell(borderData, row_index, col_index)
          // console.log('bordre', border, borderData)
          worksheet.getCell(row_index + 1, col_index + 1).border = border
        }
        // console.log(rang.column_focus + 1, rang.row_focus + 1)
        // worksheet.getCell(rang.row_focus + 1, rang.column_focus + 1).border = border
      })
    }
    var setStyleAndValue = function (cellArr, worksheet) {
      if (!Array.isArray(cellArr)) return
      cellArr.forEach(function (row, rowid) {
        row.every(function (cell, columnid) {
          if (!cell) return true
          let fill = fillConvert(cell.bg)

          let font = fontConvert(
            cell.ff,
            cell.fc,
            cell.bl,
            cell.it,
            cell.fs,
            cell.cl,
            cell.ul
          )
          let alignment = alignmentConvert(cell.vt, cell.ht, cell.tb, cell.tr)
          let value = ''

          if (cell.f) {
            value = { formula: cell.f, result: cell.v }
          } else if (!cell.v && cell.ct && cell.ct.s) {
            // xls转为xlsx之后，内部存在不同的格式，都会进到富文本里，即值不存在与cell.v，而是存在于cell.ct.s之后
            // value = cell.ct.s[0].v
            cell.ct.s.forEach(arr => {
              value += arr.v
            })
          } else {
            value = cell.v
          }
          //  style 填入到_value中可以实现填充色
          let letter = createCellPos(columnid)
          let target = worksheet.getCell(letter + (rowid + 1))
          // console.log('1233', letter + (rowid + 1))
          for (const key in fill) {
            target.fill = fill
            break
          }
          target.font = font
          target.alignment = alignment
          target.value = value

          return true
        })
      })
    }

    var fillConvert = function (bg) {
      if (!bg) {
        return {}
      }
      // const bgc = bg.replace('#', '')
      let fill = {
        type: 'pattern',
        pattern: 'solid',
        fgColor: { argb: bg.replace('#', '') }
      }
      return fill
    }

    var fontConvert = function (
      ff = 0,
      fc = '#000000',
      bl = 0,
      it = 0,
      fs = 10,
      cl = 0,
      ul = 0
    ) {
      // luckysheet：ff(样式), fc(颜色), bl(粗体), it(斜体), fs(大小), cl(删除线), ul(下划线)
      const luckyToExcel = {
        0: '微软雅黑',
        1: '宋体（Song）',
        2: '黑体（ST Heiti）',
        3: '楷体（ST Kaiti）',
        4: '仿宋（ST FangSong）',
        5: '新宋体（ST Song）',
        6: '华文新魏',
        7: '华文行楷',
        8: '华文隶书',
        9: 'Arial',
        10: 'Times New Roman ',
        11: 'Tahoma ',
        12: 'Verdana',
        num2bl: function (num) {
          return num === 0 ? false : true
        }
      }
      // 出现Bug，导入的时候ff为luckyToExcel的val

      let font = {
        name: typeof ff === 'number' ? luckyToExcel[ff] : ff,
        family: 1,
        size: fs,
        color: { argb: fc.replace('#', '') },
        bold: luckyToExcel.num2bl(bl),
        italic: luckyToExcel.num2bl(it),
        underline: luckyToExcel.num2bl(ul),
        strike: luckyToExcel.num2bl(cl)
      }

      return font
    }

    var alignmentConvert = function (
      vt = 'default',
      ht = 'default',
      tb = 'default',
      tr = 'default'
    ) {
      // luckysheet:vt(垂直), ht(水平), tb(换行), tr(旋转)
      const luckyToExcel = {
        vertical: {
          0: 'middle',
          1: 'top',
          2: 'bottom',
          default: 'top'
        },
        horizontal: {
          0: 'center',
          1: 'left',
          2: 'right',
          default: 'left'
        },
        wrapText: {
          0: false,
          1: false,
          2: true,
          default: false
        },
        textRotation: {
          0: 0,
          1: 45,
          2: -45,
          3: 'vertical',
          4: 90,
          5: -90,
          default: 0
        }
      }

      let alignment = {
        vertical: luckyToExcel.vertical[vt],
        horizontal: luckyToExcel.horizontal[ht],
        wrapText: luckyToExcel.wrapText[tb],
        textRotation: luckyToExcel.textRotation[tr]
      }
      return alignment
    }

    var borderConvert = function (borderType, style = 1, color = '#000') {
      // 对应luckysheet的config中borderinfo的的参数
      if (!borderType) {
        return {}
      }
      const luckyToExcel = {
        type: {
          'border-all': 'all',
          'border-top': 'top',
          'border-right': 'right',
          'border-bottom': 'bottom',
          'border-left': 'left'
        },
        style: {
          0: 'none',
          1: 'thin',
          2: 'hair',
          3: 'dotted',
          4: 'dashDot', // 'Dashed',
          5: 'dashDot',
          6: 'dashDotDot',
          7: 'double',
          8: 'medium',
          9: 'mediumDashed',
          10: 'mediumDashDot',
          11: 'mediumDashDotDot',
          12: 'slantDashDot',
          13: 'thick'
        }
      }
      let template = {
        style: luckyToExcel.style[style],
        color: { argb: color.replace('#', '') }
      }
      let border = {}
      if (luckyToExcel.type[borderType] === 'all') {
        border['top'] = template
        border['right'] = template
        border['bottom'] = template
        border['left'] = template
      } else {
        border[luckyToExcel.type[borderType]] = template
      }
      // console.log('border', border)
      return border
    }

    function addborderToCell (borders, row_index, col_index) {
      let border = {}
      const luckyExcel = {
        type: {
          l: 'left',
          r: 'right',
          b: 'bottom',
          t: 'top'
        },
        style: {
          0: 'none',
          1: 'thin',
          2: 'hair',
          3: 'dotted',
          4: 'dashDot', // 'Dashed',
          5: 'dashDot',
          6: 'dashDotDot',
          7: 'double',
          8: 'medium',
          9: 'mediumDashed',
          10: 'mediumDashDot',
          11: 'mediumDashDotDot',
          12: 'slantDashDot',
          13: 'thick'
        }
      }
      // console.log('borders', borders)
      for (const bor in borders) {
        // console.log(bor)
        if (borders[bor].color.indexOf('rgb') === -1) {
          border[luckyExcel.type[bor]] = {
            style: luckyExcel.style[borders[bor].style],
            color: { argb: borders[bor].color.replace('#', '') }
          }
        } else {
          border[luckyExcel.type[bor]] = {
            style: luckyExcel.style[borders[bor].style],
            color: { argb: borders[bor].color }
          }
        }
      }

      return border
    }

    function createCellPos (n) {
      let ordA = 'A'.charCodeAt(0)

      let ordZ = 'Z'.charCodeAt(0)
      let len = ordZ - ordA + 1
      let s = ''
      while (n >= 0) {
        s = String.fromCharCode((n % len) + ordA) + s

        n = Math.floor(n / len) - 1
      }
      return s
    }

    luckyExcel.transformExcelToLuckyByUrl('api/file/' + xlsxname, xlsxname, function (exportJson, luckysheetfile) {
      if (exportJson.sheets == null || exportJson.sheets.length === 0) {
        alert("Failed to read the content of the excel file, currently does not support xls files!");
        return;
      }
      for (var i = 0; i < exportJson.sheets.length; i++) {
        exportJson.sheets[i].config['authority'] = {//当前工作表的权限配置
          selectLockedCells: 1, //选定锁定单元格
          selectunLockedCells: 1, //选定解除锁定的单元格
          formatCells: 1, //设置单元格格式
          formatColumns: 1, //设置列格式
          formatRows: 1, //设置行格式
          insertColumns: 1, //插入列
          insertRows: 1, //插入行
          insertHyperlinks: 1, //插入超链接
          deleteColumns: 1, //删除列
          deleteRows: 1, //删除行
          sort: 1, //排序
          filter: 1, //使用自动筛选
          usePivotTablereports: 1, //使用数据透视表和报表
          editObjects: 1, //编辑对象
          editScenarios: 1, //编辑方案    
          sheet: 1, //如果为1或true，则该工作表受到保护；如果为0或false，则该工作表不受保护。
          hintText: "如果需要修改信息请联系管理员", //弹窗提示的文字
          algorithmName: "None",//加密方案：MD2,MD4,MD5,RIPEMD-128,RIPEMD-160,SHA-1,SHA-256,SHA-384,SHA-512,WHIRLPOOL
          saltValue: null, //密码解密的盐参数，为一个自己定的随机数值
          allowRangeList: [{ //区域保护
            name: "area", //名称
            password: "", //密码；如果此值不空，编辑时需要密码
            hintText: "编辑请输入密码，或者联系管理员", //提示文字
            algorithmName: "None",//加密方案：MD2,MD4,MD5,RIPEMD-128,RIPEMD-160,SHA-1,SHA-256,SHA-384,SHA-512,WHIRLPOOL
            saltValue: null, //密码解密的盐参数，为一个自己定的随机数值
            sqref: "$A$1:$BH$357" //区域范围
          }],
        }
      }

      luckysheet.create({
        container: "luckysheet",
        lang: 'zh',
        enableAddRow: true,
        showtoolbar: true,
        sheetRightClickConfig: {
          delete: true, // 删除
          copy: true, // 复制
          rename: true, //重命名
          color: true, //更改颜色
          hide: true, //隐藏，取消隐藏
          move: true,
        },
        plugins: ['chart'],
        cellRightClickConfig: {
          copy: true, // 复制
          copyAs: true, // 复制为
          paste: true, // 粘贴
          insertRow: true, // 插入行
          insertColumn: true, // 插入列
          deleteRow: true, // 删除选中行
          deleteColumn: true, // 删除选中列
          deleteCell: true, // 删除单元格
          hideRow: true, // 隐藏选中行和显示选中行
          hideColumn: true, // 隐藏选中列和显示选中列
          rowHeight: true, // 行高
          columnWidth: true, // 列宽
          clear: true, // 清除内容
          matrix: true, // 矩阵操作选区
          sort: true, // 排序选区
          filter: true, // 筛选选区
          chart: true, // 图表生成
          image: true, // 插入图片
          link: true, // 插入链接
          data: true, // 数据验证
          cellFormat: true // 设置单元格格式
        },
        showsheetbarConfig: {
          add: true, //新增sheet  
          menu: true, //sheet管理菜单
          sheet: true //sheet页显示
        },
        showinfobar: true,
        data: exportJson.sheets,
        title: xlsxname,
        userInfo: "HBFEC"
      });
    });

    document.querySelector("body").insertAdjacentHTML('beforeend', '<a id="Luckyexcel-save-file" href = "javascript:void(0)" target = "_self" style = "z-index:2;width:50px;height:50px;line-height:50px;position:fixed;right:40px;bottom:86px;border-radius:50px;cursor:pointer;background:rgb(71,133,249);color:#fff;text-align:center;text-decoration:none;" >保存</a > ');
    document.getElementById("Luckyexcel-save-file").addEventListener("click", function (evt) {
      exportExcel(luckysheet.getAllSheets(), xlsxname);
    });
  }
  render () {
    const luckyCss = {
      margin: '0px',
      padding: '0px',
      position: 'absolute',
      width: '100%',
      height: '100%',
      left: '0px',
      top: '0px',
      outline: 'none'
    };
    return (

      <div
        id="luckysheet"
        style={luckyCss}
      >
      </div>
    )
  }
}

export default Luckysheet